const HashTable = require("../template")

function testHashTableResizing() {
  console.log(
    "1. 基本扩容测试:",
    (() => {
      const ht = new HashTable(4, 0.5) // 低负载因子，容易触发扩容
      
      // 插入数据直到触发扩容
      ht.set('key1', 'value1')
      ht.set('key2', 'value2')
      ht.set('key3', 'value3')
      
      const initialCapacity = ht.getCapacity()
      const initialLoadFactor = ht.getLoadFactor()
      
      // 继续插入触发扩容
      ht.set('key4', 'value4')
      
      const finalCapacity = ht.getCapacity()
      const finalLoadFactor = ht.getLoadFactor()
      
      return initialCapacity === 4 &&
             finalCapacity > initialCapacity &&
             ht.get('key1') === 'value1' &&
             ht.get('key2') === 'value2' &&
             ht.get('key3') === 'value3' &&
             ht.get('key4') === 'value4' &&
             ht.size() === 4
    })()
  )

  console.log(
    "2. 扩容后数据完整性测试:",
    (() => {
      const ht = new HashTable(2, 0.75)
      
      // 插入数据
      const testData = [
        ['a', 1], ['b', 2], ['c', 3], ['d', 4], 
        ['e', 5], ['f', 6], ['g', 7], ['h', 8]
      ]
      
      testData.forEach(([key, value]) => ht.set(key, value))
      
      // 验证所有数据都能正确获取
      const allCorrect = testData.every(([key, value]) => ht.get(key) === value)
      
      return allCorrect && 
             ht.size() === testData.length &&
             ht.getCapacity() > 2
    })()
  )

  console.log(
    "3. 扩容后键值对遍历测试:",
    (() => {
      const ht = new HashTable(2, 0.5)
      
      const testData = [['a', 1], ['b', 2], ['c', 3], ['d', 4]]
      testData.forEach(([key, value]) => ht.set(key, value))
      
      const keys = ht.keys()
      const values = ht.values()
      const entries = ht.entries()
      
      const keysCorrect = testData.every(([key]) => keys.includes(key))
      const valuesCorrect = testData.every(([, value]) => values.includes(value))
      const entriesCorrect = testData.every(([key, value]) => 
        entries.some(([k, v]) => k === key && v === value)
      )
      
      return keysCorrect && valuesCorrect && entriesCorrect &&
             keys.length === testData.length &&
             values.length === testData.length &&
             entries.length === testData.length
    })()
  )

  console.log(
    "4. 多次扩容测试:",
    (() => {
      const ht = new HashTable(2, 0.5)
      
      // 插入大量数据触发多次扩容
      for (let i = 0; i < 20; i++) {
        ht.set(`key${i}`, `value${i}`)
      }
      
      // 验证所有数据都能正确获取
      let allCorrect = true
      for (let i = 0; i < 20; i++) {
        if (ht.get(`key${i}`) !== `value${i}`) {
          allCorrect = false
          break
        }
      }
      
      return allCorrect && 
             ht.size() === 20 &&
             ht.getCapacity() >= 20
    })()
  )

  console.log(
    "5. 扩容后删除测试:",
    (() => {
      const ht = new HashTable(2, 0.5)
      
      // 插入数据触发扩容
      for (let i = 0; i < 10; i++) {
        ht.set(`key${i}`, `value${i}`)
      }
      
      const capacityAfterInsert = ht.getCapacity()
      
      // 删除部分数据
      for (let i = 0; i < 5; i++) {
        ht.delete(`key${i}`)
      }
      
      // 验证剩余数据正确
      let remainingCorrect = true
      for (let i = 5; i < 10; i++) {
        if (ht.get(`key${i}`) !== `value${i}`) {
          remainingCorrect = false
          break
        }
      }
      
      // 验证删除的数据不存在
      let deletedCorrect = true
      for (let i = 0; i < 5; i++) {
        if (ht.get(`key${i}`) !== undefined) {
          deletedCorrect = false
          break
        }
      }
      
      return remainingCorrect && 
             deletedCorrect &&
             ht.size() === 5 &&
             ht.getCapacity() === capacityAfterInsert
    })()
  )

  console.log(
    "6. 负载因子计算测试:",
    (() => {
      const ht = new HashTable(4, 0.75)
      
      ht.set('a', 1)
      ht.set('b', 2)
      ht.set('c', 3)
      
      const loadFactor1 = ht.getLoadFactor()
      
      ht.set('d', 4)
      
      const loadFactor2 = ht.getLoadFactor()
      
      return loadFactor1 === 0.75 && // 3/4 = 0.75
             loadFactor2 < loadFactor1 && // 扩容后负载因子降低
             ht.getCapacity() > 4
    })()
  )

  console.log(
    "7. 扩容边界条件测试:",
    (() => {
      const ht = new HashTable(1, 0.5) // 最小容量
      
      ht.set('a', 1)
      const capacity1 = ht.getCapacity()
      
      ht.set('b', 2)
      const capacity2 = ht.getCapacity()
      
      return capacity1 === 1 &&
             capacity2 > capacity1 &&
             ht.get('a') === 1 &&
             ht.get('b') === 2 &&
             ht.size() === 2
    })()
  )

  console.log(
    "8. 扩容后更新测试:",
    (() => {
      const ht = new HashTable(2, 0.5)
      
      // 插入数据触发扩容
      ht.set('a', 1)
      ht.set('b', 2)
      ht.set('c', 3)
      
      // 更新已存在的键
      ht.set('a', 'updated_a')
      ht.set('b', 'updated_b')
      
      return ht.get('a') === 'updated_a' &&
             ht.get('b') === 'updated_b' &&
             ht.get('c') === 3 &&
             ht.size() === 3
    })()
  )

  console.log(
    "9. this上下文扩容测试:",
    (() => {
      const resizeObj = {
        multiplier: 2,
        processResize: function(entries) {
          const ht = new HashTable(2, 0.5) // 容易触发扩容
          entries.forEach(([key, value]) => ht.set(key, value))
          return ht.getCapacity() * this.multiplier
        }
      }
      return resizeObj.processResize([['a', 1], ['b', 2], ['c', 3], ['d', 4]]) > 4
    })()
  )

  console.log(
    "10. 复杂对象this绑定扩容测试:",
    (() => {
      const resizeConfigObj = {
        config: { threshold: 2 },
        processWithConfig: function(entries) {
          const ht = new HashTable(2, 0.5)
          entries.forEach(([key, value]) => ht.set(key, value))
          return ht.getCapacity() >= this.config.threshold * 2
        }
      }
      return resizeConfigObj.processWithConfig([['a', 1], ['b', 2], ['c', 3], ['d', 4]]) === true
    })()
  )

  console.log(
    "11. 扩容一致性测试:",
    (() => {
      const consistencyHt = new HashTable(2, 0.5)
      
      // 插入数据
      consistencyHt.set('key1', 'value1')
      consistencyHt.set('key2', 'value2')
      consistencyHt.set('key3', 'value3')
      
      const size1 = consistencyHt.size()
      const capacity1 = consistencyHt.getCapacity()
      
      // 继续插入
      consistencyHt.set('key4', 'value4')
      
      const size2 = consistencyHt.size()
      const capacity2 = consistencyHt.getCapacity()
      
      return size1 === 3 && 
             size2 === 4 &&
             capacity2 > capacity1 &&
             consistencyHt.get('key1') === 'value1' &&
             consistencyHt.get('key4') === 'value4'
    })()
  )

  console.log(
    "12. 扩容性能测试:",
    (() => {
      const perfHt = new HashTable(2, 0.5)
      
      const start = performance.now()
      
      // 插入大量数据触发多次扩容
      for (let i = 0; i < 1000; i++) {
        perfHt.set(`key${i}`, `value${i}`)
      }
      
      const end = performance.now()
      
      // 验证所有数据都能正确获取
      let allCorrect = true
      for (let i = 0; i < 1000; i++) {
        if (perfHt.get(`key${i}`) !== `value${i}`) {
          allCorrect = false
          break
        }
      }
      
      return allCorrect && 
             perfHt.size() === 1000 &&
             (end - start) < 1000 // 性能测试
    })()
  )
}

testHashTableResizing()
